#!/usr/bin/env python
"""
RNA design based on context-free grammars and finite state automata
"""

import os
import sys
import optparse
from pyrna.design import CfgRNADesign
from pyrna.param import Param
from pyrna import utils
    
###############################################################################

def process_command_line(argv):
    if argv is None:
        argv = sys.argv[1:]

    usage = """usage: %s [options]
example: %s -s 'NNNN' -u '(..)' -o test
""" % (sys.argv[0], sys.argv[0])
    parser = optparse.OptionParser(usage,
        formatter=optparse.TitledHelpFormatter(width=80),
        add_help_option=None)
    
    parser.add_option("-u", "--structure", dest="structure",
        help="expected structure", metavar="str")
    
    parser.add_option("-s", "--sequence", dest="sequence",
        help="expected sequence", metavar="str")
    
    parser.add_option("-m", "--mandatory", dest="mandatory_motif",
        help="mandatory motif in the sequence", metavar="str")
                      
    parser.add_option("-b", "--forbidden", dest="forbidden_set",
        help="file of forbidden motifs", metavar="FILE")
    
    parser.add_option("-g", "--gen", dest="gen", default=None, 
        help="number of random set of compatible sequences", type="int")

    parser.add_option("-o", "--outprefix", dest="outprefix",
        help="output prefix", metavar="str")
    
    parser.add_option("-d", action="store_true", dest="debug",
        help='turns on debug messages')
        
    parser.add_option('-h', '--help', action='help',
        help='Show this help message and exit.')
    
    (options, args) = parser.parse_args(argv)
    if not options.sequence:
        parser.error('--sequence required')
    if not options.structure:
        parser.error('--structure required')
    if not options.outprefix:
        parser.error('--outprefix required')
        
    return options, args

###############################################################################

def main(options, args):
    if utils.which('fsa') is None:
        sys.stderr.write("program fsa needs to be in PATH.\n")
        sys.exit(1)

    if utils.which('grgfreqs') is None:
        sys.stderr.write("program grgfreqs needs to be in PATH.\n")
        sys.exit(1)
        
    # set mode
    if options.debug:
        utils.disable_loglevel(0)
        utils.debug_on()
    else:
        utils.disable_loglevel('DEBUG')
        utils.debug_off()
    
    # read parameters
    assert len(options.sequence) == len(options.structure)
    p = Param() 
    p.set_one('seq', options.sequence)
    p.set_one('struct', options.structure)
    p.set_one('mda_motif', options.mandatory_motif)
    p.set_one('fbdn', options.forbidden_set)
    p.set_one('outprefix', options.outprefix)
    p.set_one('gen', options.gen)
    p.check()
    
    # design   
    designer = CfgRNADesign(p)
    designer.design()
    sys.stderr.write('#candidates: %d\n' % designer.get_num_candidates())

###############################################################################

if __name__ == '__main__':
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass
    
    options, args = process_command_line(sys.argv)
    main(options, args)
    
